﻿using System;
using System.Collections.Generic;
using System.Threading;

namespace Jayden.Dll.Core.Persistence
{
	public class IdentityMap : Dictionary<Key, Object>
	{
		private ReaderWriterLock m_ReaderWriterLock = new ReaderWriterLock();
		private IdentityMap m_Parent = null;

		public IdentityMap Parent { get { return m_Parent; } set { m_Parent = value; } }

		public Object GetRegistered(Key key) {
			Object obj;
			if (TryGetValue(key, out obj))
				return obj;
			if (m_Parent != null)
				return m_Parent.GetRegisteredThreadSafe(key);
			return null;
		}

		public void Register(Object obj)
		{
			try
			{
				Add(obj.ObjectId, obj);
			}
			catch (Exception e)
			{
#if DEBUG
				Object alreadyRegistered = this[obj.ObjectId];
				if (!alreadyRegistered.Equals(obj))
					throw e;
#endif
			}
		}

		public void RegisterThreadSafe(Object obj)
		{
			try
			{
				m_ReaderWriterLock.AcquireWriterLock(1000);
				try
				{
					Register(obj);
				}
				finally
				{
					m_ReaderWriterLock.ReleaseWriterLock();
				}
			}
			catch (Exception e)
			{
			}
		}

		public Object GetRegisteredThreadSafe(Key key)
		{
			try
			{
				m_ReaderWriterLock.AcquireReaderLock(1000);
				try
				{
					return GetRegistered(key);
				}
				finally
				{
					m_ReaderWriterLock.ReleaseReaderLock();
				}
			}
			catch (Exception e)
			{
			}
			return null;
		}
	}
}
